<template>
  <div>
    <el-card style="height: 75px; margin-bottom: 10px">
      <el-form inline class="form-inline">
        <el-form-item label="角色名">
          <el-input v-model="roleName" />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="search">搜索</el-button>
          <el-button @click="reset">重置</el-button>
        </el-form-item>
      </el-form>
    </el-card>
    <el-card>
      <el-button type="primary" @click="handleAdd">添加角色</el-button>
      <el-button type="danger" @click="handleBatchDelete">批量删除</el-button>
      <el-table :data="tableData" border style="margin: 10px 0" ref="tableRef">
        <el-table-column type="selection" width="55" align="center" />
        <el-table-column prop="id" label="ID" width="100" />
        <el-table-column prop="roleName" label="角色名" show-overflow-tooltip />
        <el-table-column prop="remark" label="备注" show-overflow-tooltip />
        <el-table-column prop="createTime" label="创建时间" width="170" />
        <el-table-column prop="updateTime" label="更新时间" width="170" />
        <el-table-column label="操作" fixed="right" width="220" align="center">
          <template #="{ row }">
            <el-button
              type="success"
              size="small"
              @click="handleAssignPermission(row)"
              >分配权限</el-button
            >
            <el-button type="primary" size="small" @click="handleEdit(row)"
              >编辑</el-button
            >
            <el-popconfirm
              width="220"
              icon="Delete"
              :title="`是否删除${row.roleName}？`"
              @confirm="handleDelete(row.id)"
            >
              <template #reference>
                <el-button type="danger" size="small">删除</el-button>
              </template>
            </el-popconfirm>
          </template>
        </el-table-column>
      </el-table>
      <el-pagination
        v-model:current-page="pageNo"
        v-model:page-size="limit"
        :page-sizes="[3, 5, 10, 15]"
        :total="total"
        layout="prev, pager, next, total, ->, sizes, jumper"
        size="small"
        background
        @change="handleChange"
      />
    </el-card>
    <el-drawer
      :title="roleInfo.id ? '编辑' : '新增' + `角色`"
      v-model="drawerVisible"
      @close="drawerClosed"
    >
      <el-form
        :model="roleInfo"
        ref="roleInfoRef"
        :rules="rules"
        label-width="80"
      >
        <el-form-item label="角色名" prop="roleName">
          <el-input v-model="roleInfo.roleName" />
        </el-form-item>
        <el-form-item label="备注" prop="remark">
          <el-input v-model="roleInfo.remark" type="textarea" />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="saveRoleInfo">保存</el-button>
          <el-button @click="drawerClosed">取消</el-button>
        </el-form-item>
      </el-form>
    </el-drawer>
    <el-drawer
      title="分配权限"
      v-model="permissionDrawerVisible"
      @close="permissionDrawerClosed"
      :destroy-on-close="true"
    >
      <el-tree
        ref="treeRef"
        :data="permissionData"
        show-checkbox
        default-expand-all
        node-key="id"
        :props="defaultProps"
      />
      <el-button type="primary" @click="assignPermission">保存</el-button>
      <el-button @click="permissionDrawerClosed">取消</el-button>
    </el-drawer>
  </div>
</template>
<script setup lang="ts">
import { ref, onMounted, reactive, nextTick } from 'vue'
import {
  reqGetRoleList,
  reqDeleteRole,
  reqBatchDelete,
  reqAddRole,
  reqUpdateRole,
  reqGetPermission,
  reqGetAllPermission,
  reqAssignPermissionToRole
} from '@/api/acl/role'
let roleName = ref('')
const tableData = ref([])
const search = () => {
  getRoleList()
}
const reset = () => {
  roleName.value = ''
  getRoleList()
}

const getRoleList = () => {
  reqGetRoleList(pageNo.value, limit.value, roleName.value).then((result) => {
    if (result.code === 200) {
      tableData.value = result.data.records
      total.value = result.data.total
    }
  })
}
onMounted(() => {
  getRoleList()
  getAllPermission()
})
const handleAdd = () => {
  Object.assign(roleInfo, {
    id: undefined,
    roleName: '',
    remark: '',
    permissionIdList: []
  })
  drawerVisible.value = true
}
const tableRef = ref()
const handleBatchDelete = () => {
  const ids = tableRef.value.getSelectionRows().map((item: any) => item.id)
  reqBatchDelete(ids).then((res) => {
    if (res.code === 200) {
      getRoleList()
    }
  })
}
const handleEdit = (row: any) => {
  Object.assign(roleInfo, row)
  drawerVisible.value = true
}
const handleDelete = (id: number) => {
  reqDeleteRole(id).then((res) => {
    if (res.code === 200) {
      getRoleList()
    }
  })
}

let pageNo = ref(1)
let limit = ref(10)
let total = ref(0)
const handleChange = () => {
  getRoleList()
}

const roleInfo = reactive({
  id: undefined,
  roleName: '',
  remark: '',
  permissionIdList: []
})
let drawerVisible = ref(false)
const drawerClosed = () => {
  drawerVisible.value = false
}
const rules = reactive({
  roleName: [
    { required: true, message: '请输入角色名', trigger: 'blur' },
    { min: 3, max: 5, message: '长度在 3 到 5 个字符', trigger: 'blur' }
  ]
})
const roleInfoRef = ref()
const saveRoleInfo = () => {
  roleInfoRef.value.validate((valid: any) => {
    if (!valid) return
    const api = roleInfo.id ? reqUpdateRole : reqAddRole
    api(roleInfo).then((res) => {
      if (res.code === 200) {
        drawerClosed()
        getRoleList()
      }
    })
  })
}
const permissionData = ref([])
const getAllPermission = () => {
  reqGetAllPermission().then((res) => {
    if (res.code === 200) {
      permissionData.value = res.data
    }
  })
}
const defaultProps = {
  children: 'children',
  label: 'name'
}

let permissionDrawerVisible = ref(false)
const treeRef = ref()
const handleAssignPermission = (row: any) => {
  Object.assign(roleInfo, { id: row.id, permissionIdList: [] })
  reqGetPermission(row.id).then((res) => {
    if (res.code === 200) {
      filterData(res.data, roleInfo.permissionIdList)
      permissionDrawerVisible.value = true
      nextTick(() => {
        treeRef.value!.setCheckedKeys(roleInfo.permissionIdList)
      })
    }
  })
}
const permissionDrawerClosed = () => {
  permissionDrawerVisible.value = false
}
const assignPermission = () => {
  const checkedIds = treeRef.value!.getCheckedKeys()
  const halfCheckedIds = treeRef.value!.getHalfCheckedKeys()
  reqAssignPermissionToRole(roleInfo.id, [
    ...checkedIds,
    ...halfCheckedIds
  ]).then((res) => {
    if (res.code === 200) {
      permissionDrawerClosed()
      getRoleList()
    }
  })
}

const filterData = (list: any, newList: any) => {
  list.map((item: any) => {
    if (item.select && (!item.children || item.children.length < 1))
      newList.push(item.id)
    else filterData(item.children, newList)
  })
}
</script>
<style lang="scss" scoped>
.form-inline {
  display: flex;
  justify-content: space-between;
}
</style>
